﻿/*************************************************************************************
 * 文 件 名:   HK_RoamingCamMouseLook
 * 
 * 描    述:   RoamingCam的控制相机抚养功能脚本
 * 
 * 版    本：  V1.0
 * 创 建 者：  谭潇杰、京产肠饭
 * 创建时间：  2022/1/28
 * 链   接：  https://gitee.com/JingChanChangFan/hk_-unity-tools
*************************************************************************************/

using System;
using UnityEngine;
using UnityEngine.EventSystems;

namespace HKTools
{
    [Serializable]
    public class HK_RoamingCamMouseLook
    {

        [SerializeField] float XSensitivity = 3f;
        [SerializeField] float YSensitivity = 3f;

        [Header("摄像机俯仰角："), SerializeField]
        float MinimumX = -25f;
        [SerializeField]
        float MaximumX = 40f;

        [Header("是否平滑运动："), SerializeField]
        float smoothSpeed = 10f;

        Quaternion characterTargetRot;
        Quaternion cameraTargetRot;

        public void Init(Transform character, Transform camera)
        {
            characterTargetRot = character.localRotation;
            cameraTargetRot = camera.localRotation;
        }

        //------------ PC端控制 --------------

        float yRot, xRot;

        Ray ray;
        RaycastHit hit;

        public void PCLookRotation(Transform character, Transform camera)
        {
            if (Input.GetMouseButton(0))
            {
                ray = Camera.main.ScreenPointToRay(Input.mousePosition);
                Physics.Raycast(ray, out hit, 500); //如果碰撞检测到物体

                yRot = Input.GetAxis("Mouse X") * XSensitivity;
                xRot = Input.GetAxis("Mouse Y") * YSensitivity;
                characterTargetRot *= Quaternion.Euler(0f, yRot, 0f);
                cameraTargetRot *= Quaternion.Euler(-xRot, 0f, 0f);

                cameraTargetRot = ClampRotationAroundXAxis(cameraTargetRot);
            }

            character.localRotation = Quaternion.Slerp(character.localRotation, characterTargetRot,
                smoothSpeed * Time.deltaTime);
            camera.localRotation = Quaternion.Slerp(camera.localRotation, cameraTargetRot,
                smoothSpeed * Time.deltaTime);
        }

        //------------ 移动端控制 --------------

        Touch touch;

        public void MobileLookRoatation(Transform character, Transform camera)
        {
            if (Input.touchCount >= 1)
            {
                touch = Input.GetTouch(0);
                ray = Camera.main.ScreenPointToRay(touch.position);
                Physics.Raycast(ray, out hit, 500);
            }

            if (EventSystem.current.IsPointerOverGameObject() && hit.collider == null)
                return;

            if (touch.phase == TouchPhase.Began)
            {
                yRot = 0;
                xRot = 0;
            }

            if (touch.phase == TouchPhase.Moved)
            {
                yRot = touch.deltaPosition.x * 0.18f;
                xRot = touch.deltaPosition.y * 0.18f;
                characterTargetRot *= Quaternion.Euler(0f, -yRot, 0f);
                cameraTargetRot *= Quaternion.Euler(xRot, 0f, 0f);
            }

            cameraTargetRot = ClampRotationAroundXAxis(cameraTargetRot);

            character.localRotation = Quaternion.Slerp(character.localRotation, characterTargetRot,
                smoothSpeed * Time.deltaTime);
            camera.localRotation = Quaternion.Slerp(camera.localRotation, cameraTargetRot,
                smoothSpeed * Time.deltaTime);
        }

        // 限制摄像机俯仰角
        float angleX;

        Quaternion ClampRotationAroundXAxis(Quaternion q)
        {
            q.x /= q.w;
            q.y /= q.w;
            q.z /= q.w;
            q.w = 1.0f;

            angleX = 2.0f * Mathf.Rad2Deg * Mathf.Atan(q.x);
            angleX = Mathf.Clamp(angleX, MinimumX, MaximumX);
            q.x = Mathf.Tan(0.5f * Mathf.Deg2Rad * angleX);

            return q;
        }
    }
}